<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Highscore - The Boost C++ Libraries - Date and Time</title>
<link rel="stylesheet" href="css/highscore.css" type="text/css">
<link rev="made" href="mailto:boris@highscore.de">
<link rel="home" href="frontpage.html" title="The Boost C++ Libraries">
<link rel="up" href="frontpage.html" title="The Boost C++ Libraries">
<link rel="prev" href="filesystem.html" title="Chapter 9: Filesystem">
<link rel="next" href="serialization.html" title="Chapter 11: Serialization">
<link rel="chapter" href="introduction.html" title="Chapter 1: Introduction">
<link rel="chapter" href="smartpointers.html" title="Chapter 2: Smart Pointers">
<link rel="chapter" href="functionobjects.html" title="Chapter 3: Function Objects">
<link rel="chapter" href="eventhandling.html" title="Chapter 4: Event Handling">
<link rel="chapter" href="stringhandling.html" title="Chapter 5: String Handling">
<link rel="chapter" href="multithreading.html" title="Chapter 6: Multithreading">
<link rel="chapter" href="asio.html" title="Chapter 7: Asynchronous Input and Output">
<link rel="chapter" href="interprocesscommunication.html" title="Chapter 8: Interprocess Communication">
<link rel="chapter" href="filesystem.html" title="Chapter 9: Filesystem">
<link rel="chapter" href="datetime.html" title="Chapter 10: Date and Time">
<link rel="chapter" href="serialization.html" title="Chapter 11: Serialization">
<link rel="chapter" href="parser.html" title="Chapter 12: Parser">
<link rel="chapter" href="containers.html" title="Chapter 13: Containers">
<link rel="chapter" href="datastructures.html" title="Chapter 14: Data Structures">
<link rel="chapter" href="errorhandling.html" title="Chapter 15: Error Handling">
<link rel="chapter" href="castoperators.html" title="Chapter 16: Cast Operators">
<link rel="section" href="datetime.html#datetime_general" title="10.1 General">
<link rel="section" href="datetime.html#datetime_calendar" title="10.2 Calendar Dates">
<link rel="section" href="datetime.html#datetime_location_independent_times" title="10.3 Location-independent Times">
<link rel="section" href="datetime.html#datetime_location_dependent_times" title="10.4 Location-dependent Times">
<link rel="section" href="datetime.html#datetime_formatted_io" title="10.5 Formatted Input and Output">
<link rel="section" href="datetime.html#datetime_exercises" title="10.6 Exercises">
<meta http-equiv="pics-label" content='(pics-1.1 "http://www.icra.org/ratingsv02.html" l gen true for "http://www.highscore.de" r (nz 1 vz 1 lz 1 oz 1 cz 1) gen true for "http://highscore.de" r (nz 1 vz 1 lz 1 oz 1 cz 1))'>
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<link href="http://www.highscore.de/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon">
<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script><script type="text/javascript" src="js/jquery.event.drag-1.5.min.js"></script><script type="text/javascript" src="js/highscore.js"></script>
</head>
<body>
<div lang="en" class="docbook chapter" title="Chapter 10: Date and Time">
<p class="title">The Boost C++ Libraries</p>
<script type="text/javascript">
          var titlepage = "Front page";
        
      var titles = new Array(titlepage,
      
        "Chapter 1: Introduction",
      
        "Chapter 2: Smart Pointers",
      
        "Chapter 3: Function Objects",
      
        "Chapter 4: Event Handling",
      
        "Chapter 5: String Handling",
      
        "Chapter 6: Multithreading",
      
        "Chapter 7: Asynchronous Input and Output",
      
        "Chapter 8: Interprocess Communication",
      
        "Chapter 9: Filesystem",
      
        "Chapter 10: Date and Time",
      
        "Chapter 11: Serialization",
      
        "Chapter 12: Parser",
      
        "Chapter 13: Containers",
      
        "Chapter 14: Data Structures",
      
        "Chapter 15: Error Handling",
      
        "Chapter 16: Cast Operators",
      
      "");

      
          var titlehtml = "frontpage.html";
        
      var filenames = new Array(titlehtml,
      
        "introduction.html",
      
        "smartpointers.html",
      
        "functionobjects.html",
      
        "eventhandling.html",
      
        "stringhandling.html",
      
        "multithreading.html",
      
        "asio.html",
      
        "interprocesscommunication.html",
      
        "filesystem.html",
      
        "datetime.html",
      
        "serialization.html",
      
        "parser.html",
      
        "containers.html",
      
        "datastructures.html",
      
        "errorhandling.html",
      
        "castoperators.html",
      
      "");

      
      document.open();
      document.write('<form action="" class="toc">');
      document.write('<select size="1" onchange="location.href=options[selectedIndex].value">');
      for (var i = 0; i < titles.length && i < filenames.length; ++i) {
        if (titles[i] != "" && filenames[i] != "") {
          document.write('<option');
          document.write(' value="' + filenames[i] + '"');
          var expr = new RegExp('[/\]' + filenames[i] + '$');
          if (expr.test(location.href)) {
            document.write(' selected="selected"');
          }
          document.write('>' + titles[i] + '<\/option>');
        }
      }
      document.write('<\/select>');
      document.write('<\/form>');
      document.close();
      
    </script><noscript><p class="toc"><a href="toc.html">Table of Contents</a></p></noscript>
<hr class="hrhead">
<h1 class="title">
<a name="datetime"></a><small>Chapter 10:</small> Date and Time</h1>
<hr>
<div class="toc">
<h3>Table of Contents</h3>
<ul>
<li><span class="sect1"><a href="datetime.html#datetime_general">10.1 General</a></span></li>
<li><span class="sect1"><a href="datetime.html#datetime_calendar">10.2 Calendar Dates</a></span></li>
<li><span class="sect1"><a href="datetime.html#datetime_location_independent_times">10.3 Location-independent Times</a></span></li>
<li><span class="sect1"><a href="datetime.html#datetime_location_dependent_times">10.4 Location-dependent Times</a></span></li>
<li><span class="sect1"><a href="datetime.html#datetime_formatted_io">10.5 Formatted Input and Output</a></span></li>
<li><span class="sect1"><a href="datetime.html#datetime_exercises">10.6 Exercises</a></span></li>
</ul>
</div>
<p class="license"><a href="http://creativecommons.org/licenses/by-nc-nd/3.0/" rel="license" target="_top"><img src="img/88x31_cc_logo.gif" alt="" width="88" height="31"></a> This book is licensed under a <a href="http://creativecommons.org/licenses/by-nc-nd/3.0/" rel="license" target="_top">Creative Commons License</a>.</p>
<hr>
<h2 class="title">
<a name="datetime_general"></a>10.1 General</h2>
<div class="sect1"><p>The library <a class="link" href="http://www.boost.org/libs/date_time/">Boost.DateTime</a> can be used to process time data such as calendar dates and times. In addition, Boost.DateTime provides extensions to account for time zones as well as supporting formatted input and output of calendar dates and times. This chapter covers the individual pieces of Boost.DateTime.</p></div>
<hr>
<h2 class="title">
<a name="datetime_calendar"></a>10.2 Calendar Dates</h2>
<div class="sect1">
<p>Boost.DateTime only supports calendar dates based on the Gregorian calendar which in general is not a problem since it is the most widely-used calendar. If a meeting with someone from a different country is arranged for January 5, 2010, it can be expected that there is no need to advise the person that the date is based on the Gregorian calendar.</p>
<p>The Gregorian calendar was introduced by Pope Gregory XIII in 1582. Strictly speaking, Boost.DateTime supports calendar dates for the years 1400 to 9999 which means that support goes back beyond the year 1582. Therefore, Boost.DateTime can be used for any calendar date after the year 1400 when converted to the Gregorian calendar. If older years are required, a different library must be used instead.</p>
<p>Classes and functions to process calendar dates are offered within the namespace <code class="code">boost::gregorian</code> defined in  <code class="filename">boost/date_time/gregorian/gregorian.hpp</code>. To create a date, the <code class="classname">boost::gregorian::date</code> class is used.</p>
<pre class="programlisting">#include &lt;boost/date_time/gregorian/gregorian.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::gregorian::date d(2010, 1, 30); 
  std::cout &lt;&lt; d.year() &lt;&lt; std::endl; 
  std::cout &lt;&lt; d.month() &lt;&lt; std::endl; 
  std::cout &lt;&lt; d.day() &lt;&lt; std::endl; 
  std::cout &lt;&lt; d.day_of_week() &lt;&lt; std::endl; 
  std::cout &lt;&lt; d.end_of_month() &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/10.2.1/main.cpp">Download source code</a></li></ul>
<p><code class="classname">boost::gregorian::date</code> offers multiple constructors to manipulate the date creation. The most basic constructor takes a year, a month and a day as its arguments. If an invalid value is given, an exception of type <code class="exceptionname">boost::gregorian::bad_year</code>, <code class="exceptionname">boost::gregorian::bad_month</code> or <code class="exceptionname">boost::gregorian::bad_day_of_month</code>, all derived from <code class="exceptionname">std::out_of_range</code>, is thrown.</p>
<p>As shown in the example, there are many methods provided to access a date. While methods such as <code class="methodname">year()</code>, <code class="methodname">month()</code> and <code class="methodname">day()</code> access the initial values used for initialization, methods like <code class="methodname">day_of_week()</code> and <code class="methodname">end_of_month()</code> specifically calculate values.</p>
<p>Whilst the constructor of <code class="classname">boost::gregorian::date</code> takes values for the year, month and day to set a date, calling the <code class="methodname">month()</code> method actually displays <code class="computeroutput">Jan</code> while calling the <code class="methodname">day_of_week()</code> displays <code class="computeroutput">Sat</code>. These are no regular numeric values but rather values of type <code class="type">boost::gregorian::date::month_type</code> and <code class="type">boost::gregorian::date::day_of_week_type</code>, respectively. Nonetheless, Boost.DateTime offers comprehensive support for formatted input and output to adjust the above output from <code class="computeroutput">Jan</code> to <code class="computeroutput">1</code>.</p>
<p>Please note that an invalid date is created by the default constructor of <code class="classname">boost::gregorian::date</code>. Such an invalid date can be created explicitly by passing <code class="code">boost::date_time::not_a_date_time</code> as the single argument to the constructor.</p>
<p>Besides calling a constructor directly, an object of type <code class="classname">boost::gregorian::date</code> can also be created via free-standing functions and methods of other objects.</p>
<pre class="programlisting">#include &lt;boost/date_time/gregorian/gregorian.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::gregorian::date d = boost::gregorian::day_clock::universal_day(); 
  std::cout &lt;&lt; d.year() &lt;&lt; std::endl; 
  std::cout &lt;&lt; d.month() &lt;&lt; std::endl; 
  std::cout &lt;&lt; d.day() &lt;&lt; std::endl; 

  d = boost::gregorian::date_from_iso_string("20100131"); 
  std::cout &lt;&lt; d.year() &lt;&lt; std::endl; 
  std::cout &lt;&lt; d.month() &lt;&lt; std::endl; 
  std::cout &lt;&lt; d.day() &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/10.2.2/main.cpp">Download source code</a></li></ul>
<p>This example utilizes the <code class="classname">boost::gregorian::day_clock</code> class which is a clock returning the current date. The <code class="methodname">universal_day()</code> returns a UTC date that is independent of time zones and daylight savings. UTC is the international abbreviation for the universal time. <code class="classname">boost::gregorian::day_clock</code> also provides a method named <code class="methodname">local_day()</code> which takes the local settings into account. To retrieve the current date within the local time zone, <code class="methodname">local_day()</code> must be used.</p>
<p>The namespace <code class="code">boost::gregorian</code> contains many additional free-standing functions to convert a date stored in a string to an object of type <code class="classname">boost::gregorian::date</code>. The example actually converts a date given in ISO 8601 format via the <code class="function">boost::gregorian::date_from_iso_string()</code> function. Other functions such as <code class="function">boost::gregorian::from_simple_string()</code> and <code class="function">boost::gregorian::from_us_string()</code> are available as well.</p>
<p>While <code class="classname">boost::gregorian::date</code> marks a specific point in time, <code class="classname">boost::gregorian::date_duration</code> rather denotes a duration.</p>
<pre class="programlisting">#include &lt;boost/date_time/gregorian/gregorian.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::gregorian::date d1(2008, 1, 31); 
  boost::gregorian::date d2(2008, 8, 31); 
  boost::gregorian::date_duration dd = d2 - d1; 
  std::cout &lt;&lt; dd.days() &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/10.2.3/main.cpp">Download source code</a></li></ul>
<p>Since <code class="classname">boost::gregorian::date</code> overloads the <code class="methodname">operator-()</code> operator, two points in time can be subtracted as shown above. The return value is of type <code class="classname">boost::gregorian::date_duration</code> and marks the duration between the two dates.</p>
<p>The most important method offered by <code class="classname">boost::gregorian::date_duration</code> is <code class="methodname">days()</code> which returns the number of days the duration consists of.</p>
<p>Objects of type <code class="classname">boost::gregorian::date_duration</code> can also be explicitly created by passing the number of days as the single argument to the constructor. To create a duration that involves weeks, months or years, <code class="classname">boost::gregorian::weeks</code>, <code class="classname">boost::gregorian::months</code> and <code class="classname">boost::gregorian::years</code> can be used accordingly.</p>
<pre class="programlisting">#include &lt;boost/date_time/gregorian/gregorian.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::gregorian::date_duration dd(4); 
  std::cout &lt;&lt; dd.days() &lt;&lt; std::endl; 
  boost::gregorian::weeks ws(4); 
  std::cout &lt;&lt; ws.days() &lt;&lt; std::endl; 
  boost::gregorian::months ms(4); 
  std::cout &lt;&lt; ms.number_of_months() &lt;&lt; std::endl; 
  boost::gregorian::years ys(4); 
  std::cout &lt;&lt; ys.number_of_years() &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/10.2.4/main.cpp">Download source code</a></li></ul>
<p>Neither <code class="classname">boost::gregorian::months</code> nor <code class="classname">boost::gregorian::years</code> allow to determine the number of days since months and years vary in length. Nonetheless, the usage of these classes can still make sense as shown in the following example.</p>
<pre class="programlisting">#include &lt;boost/date_time/gregorian/gregorian.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::gregorian::date d(2009, 1, 31); 
  boost::gregorian::months ms(1); 
  boost::gregorian::date d2 = d + ms; 
  std::cout &lt;&lt; d2 &lt;&lt; std::endl; 
  boost::gregorian::date d3 = d2 - ms; 
  std::cout &lt;&lt; d3 &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/10.2.5/main.cpp">Download source code</a></li></ul>
<p>The application adds one month to the given date of January 31, 2009 which results in <var>d2</var> being February 28, 2009. In the next step, one month is subtracted and <var>d3</var> becomes January 31, 2009 again. As shown, point in times as well as durations can be used in calculations. However, the specifics need to be taken into account in these scenarios. For example, starting at the last day of a month, <code class="classname">boost::gregorian::months</code> always arrives at the last day of a different month if jumped forwards or backwards which can lead to surprises.</p>
<pre class="programlisting">#include &lt;boost/date_time/gregorian/gregorian.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::gregorian::date d(2009, 1, 30); 
  boost::gregorian::months ms(1); 
  boost::gregorian::date d2 = d + ms; 
  std::cout &lt;&lt; d2 &lt;&lt; std::endl; 
  boost::gregorian::date d3 = d2 - ms; 
  std::cout &lt;&lt; d3 &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/10.2.6/main.cpp">Download source code</a></li></ul>
<p>This example is identical to the previous one with the exception of <var>d</var> being initialized with January 30, 2009. Even though this is not the last day in January, jumping forward by one month results in <var>d2</var> becoming February 28, 2009 since there is no February 30. However, when jumping backwards by one month again, <var>d3</var> this time actually becomes January 31, 2009! Since February 28, 2009 is the last day in the month, jumping backwards actually returns to the last day in January.</p>
<p>If that behavior is too confusing, it can be modified by revoking the definition of the <code class="code">BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES</code> macro. After that, the <code class="classname">boost::gregorian::weeks</code>, <code class="classname">boost::gregorian::months</code> and <code class="classname">boost::gregorian::years</code> classes are no longer available. The only class left is <code class="classname">boost::gregorian::date_duration</code> which simply jumps forward and backwards by a specified number of days so that unexpected results are no longer possible.</p>
<p>While <code class="classname">boost::gregorian::date_duration</code> works with durations, <code class="classname">boost::gregorian::date_period</code> offers support for ranges between two dates.</p>
<pre class="programlisting">#include &lt;boost/date_time/gregorian/gregorian.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::gregorian::date d1(2009, 1, 30); 
  boost::gregorian::date d2(2009, 10, 31); 
  boost::gregorian::date_period dp(d1, d2); 
  boost::gregorian::date_duration dd = dp.length(); 
  std::cout &lt;&lt; dd.days() &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/10.2.7/main.cpp">Download source code</a></li></ul>
<p>Two arguments of type <code class="classname">boost::gregorian::date</code> specifying the beginning and end dates can be passed to the constructor of <code class="classname">boost::gregorian::date_period</code>. Alternatively, the beginning date and a duration of type <code class="classname">boost::gregorian::date_duration</code> can be specified. Please note that the day before the end date is actually the last day of the period which is important in order to understand the output of the following example.</p>
<pre class="programlisting">#include &lt;boost/date_time/gregorian/gregorian.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::gregorian::date d1(2009, 1, 30); 
  boost::gregorian::date d2(2009, 10, 31); 
  boost::gregorian::date_period dp(d1, d2); 
  std::cout &lt;&lt; dp.contains(d1) &lt;&lt; std::endl; 
  std::cout &lt;&lt; dp.contains(d2) &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/10.2.8/main.cpp">Download source code</a></li></ul>
<p>The application checks for a specific date within the period using the <code class="methodname">contains()</code> method. Even though both <var>d1</var> and <var>d2</var> were passed to the constructor of <code class="classname">boost::gregorian::date_period</code>, <code class="methodname">contains()</code> returns <code class="literal">true</code> only the first time. Since the end date is not part of the period, <code class="methodname">contains()</code> returns <code class="literal">false</code> if called with <var>d2</var>.</p>
<p><code class="classname">boost::gregorian::date_period</code> offers additional methods to e.g. move a period or to calculate the intersection of two overlapping periods.</p>
<p>Besides classes for date, durations and periods, Boost.DateTime provides iterators as well as different useful free-standing functions as shown in the following example.</p>
<pre class="programlisting">#include &lt;boost/date_time/gregorian/gregorian.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::gregorian::date d(2009, 1, 5); 
  boost::gregorian::day_iterator it(d); 
  std::cout &lt;&lt; *++it &lt;&lt; std::endl; 
  std::cout &lt;&lt; boost::date_time::next_weekday(*it, boost::gregorian::greg_weekday(boost::date_time::Friday)) &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/10.2.9/main.cpp">Download source code</a></li></ul>
<p>In order to jump forward or backward by a day from a specific date, the iterator <code class="classname">boost::gregorian::day_iterator</code> can be used. With <code class="classname">boost::gregorian::week_iterator</code>, <code class="classname">boost::gregorian::month_iterator</code> and <code class="classname">boost::gregorian::year_iterator</code>, additional iterators are provided to jump by weeks, months or years.</p>
<p>The example also uses the <code class="function">boost::date_time::next_weekday()</code> which returns the date of the next weekday based on a given date. The above application displays <code class="computeroutput">2009-Jan-09</code> since this is the first Friday following January 6, 2009.</p>
</div>
<hr>
<h2 class="title">
<a name="datetime_location_independent_times"></a>10.3 Location-independent Times</h2>
<div class="sect1">
<p>While <code class="classname">boost::gregorian::date</code> creates a date, <code class="classname">boost::posix_time::ptime</code> is used to define a location-independent time. <code class="classname">boost::posix_time::ptime</code> accesses <code class="classname">boost::gregorian::date</code> but stores a time in addition.</p>
<p>In order to use <code class="classname">boost::posix_time::ptime</code> the header <code class="filename">boost/date_time/posix_time/posix_time.hpp</code> needs to be included.</p>
<pre class="programlisting">#include &lt;boost/date_time/posix_time/posix_time.hpp&gt; 
#include &lt;boost/date_time/gregorian/gregorian.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::posix_time::ptime pt(boost::gregorian::date(2009, 1, 5), boost::posix_time::time_duration(12, 0, 0)); 
  boost::gregorian::date d = pt.date(); 
  std::cout &lt;&lt; d &lt;&lt; std::endl; 
  boost::posix_time::time_duration td = pt.time_of_day(); 
  std::cout &lt;&lt; td &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/10.3.1/main.cpp">Download source code</a></li></ul>
<p>To initialize an object of type <code class="classname">boost::posix_time::ptime</code>, a date of type <code class="classname">boost::gregorian::date</code> and a duration of type <code class="classname">boost::posix_time::time_duration</code> is passed as the first and second argument to the constructor. The three arguments passed to the constructor of <code class="classname">boost::posix_time::time_duration</code> determine the time. The above application specifies 12 PM on January 5, 2009  as the point in time.</p>
<p>In order to query date and time, the <code class="methodname">date()</code> and <code class="methodname">time_of_day()</code> methods can be used.</p>
<p>Just like the default constructor of <code class="classname">boost::gregorian::date</code> creates an invalid date, a time of type <code class="classname">boost::posix_time::ptime</code> is also invalid if the default constructor is used. An invalid time can also be created explicitly by passing <code class="code">boost::date_time::not_a_date_time</code> to the constructor.</p>
<p>Similar to creating calendar dates of type <code class="classname">boost::gregorian::date</code> via the use of free-standing functions or methods of different objects, Boost.DateTime offers corresponding free-standing functions and objects to create times.</p>
<pre class="programlisting">#include &lt;boost/date_time/posix_time/posix_time.hpp&gt; 
#include &lt;boost/date_time/gregorian/gregorian.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::posix_time::ptime pt = boost::posix_time::second_clock::universal_time(); 
  std::cout &lt;&lt; pt.date() &lt;&lt; std::endl; 
  std::cout &lt;&lt; pt.time_of_day() &lt;&lt; std::endl; 

  pt = boost::posix_time::from_iso_string("20090105T120000"); 
  std::cout &lt;&lt; pt.date() &lt;&lt; std::endl; 
  std::cout &lt;&lt; pt.time_of_day() &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/10.3.2/main.cpp">Download source code</a></li></ul>
<p>The <code class="classname">boost::posix_time::second_clock</code> class represents a clock returning the current time. The <code class="methodname">universal_time()</code> method returns the UTC time as shown in the above example. If local time is preferred, <code class="methodname">local_time()</code> must be used.</p>
<p>Boost.DateTime offers an additional class named <code class="classname">boost::posix_time::microsec_clock</code> that returns the current time including microseconds in case a higher resolution is required.</p>
<p>To convert a point in time stored in a string to an object of type <code class="classname">boost::posix_time::ptime</code>, free-standing functions such as <code class="function">boost::posix_time::from_iso_string()</code> are provided which expects the point in time to be stored in the ISO 8601 format.</p>
<p>In addition to <code class="classname">boost::posix_time::ptime</code>, Boost.DateTime also offers the <code class="classname">boost::posix_time::time_duration</code> class that specifies a duration. This class has been mentioned before since the constructor of <code class="classname">boost::posix_time::ptime</code> actually expects an object of type <code class="classname">boost::posix_time::time_duration</code> as its second argument. Nonetheless, <code class="classname">boost::posix_time::time_duration</code> can certainly be used independently as well.</p>
<pre class="programlisting">#include &lt;boost/date_time/posix_time/posix_time.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::posix_time::time_duration td(16, 30, 0); 
  std::cout &lt;&lt; td.hours() &lt;&lt; std::endl; 
  std::cout &lt;&lt; td.minutes() &lt;&lt; std::endl; 
  std::cout &lt;&lt; td.seconds() &lt;&lt; std::endl; 
  std::cout &lt;&lt; td.total_seconds() &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/10.3.3/main.cpp">Download source code</a></li></ul>
<p><code class="methodname">hours()</code>, <code class="methodname">minutes()</code> and <code class="methodname">seconds()</code> all return values that are passed to the constructor while methods such as <code class="methodname">total_seconds()</code>, returning the total number of seconds, provide one with additional information in a simple way.</p>
<p>Random values can be legally passed to <code class="classname">boost::posix_time::time_duration</code> since no upper limit such as 24 hours exists.</p>
<p>As with calendar dates, calculations can also be performed with points in time and durations.</p>
<pre class="programlisting">#include &lt;boost/date_time/posix_time/posix_time.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::posix_time::ptime pt1(boost::gregorian::date(2009, 1, 05), boost::posix_time::time_duration(12, 0, 0)); 
  boost::posix_time::ptime pt2(boost::gregorian::date(2009, 1, 05), boost::posix_time::time_duration(18, 30, 0)); 
  boost::posix_time::time_duration td = pt2 - pt1; 
  std::cout &lt;&lt; td.hours() &lt;&lt; std::endl; 
  std::cout &lt;&lt; td.minutes() &lt;&lt; std::endl; 
  std::cout &lt;&lt; td.seconds() &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/10.3.4/main.cpp">Download source code</a></li></ul>
<p>If two times of type <code class="classname">boost::posix_time::ptime</code> are subtracted from each other, the result is an object of type <code class="classname">boost::posix_time::time_duration</code> specifying the duration between the two points.</p>
<pre class="programlisting">#include &lt;boost/date_time/posix_time/posix_time.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::posix_time::ptime pt1(boost::gregorian::date(2009, 1, 05), boost::posix_time::time_duration(12, 0, 0)); 
  boost::posix_time::time_duration td(6, 30, 0); 
  boost::posix_time::ptime pt2 = pt1 + td; 
  std::cout &lt;&lt; pt2.time_of_day() &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/10.3.5/main.cpp">Download source code</a></li></ul>
<p>As shown in the example, a duration can be added to a specific point in time resulting in a new point in time. The above application writes <code class="computeroutput">18:30:00</code> to the standard output stream.</p>
<p>As one may have been noticed, Boost.DateTime uses the same concepts for both calendar dates and times. Just like there are classes for times and durations, there is also one for periods. For calendar dates, this class is <code class="classname">boost::gregorian::date_period</code>; for times it is <code class="classname">boost::posix_time::time_period</code>. Both classes expect two arguments being passed to the constructor: <code class="classname">boost::gregorian::date_period</code> expects two calendar dates while <code class="classname">boost::posix_time::time_period</code> expects two times.</p>
<pre class="programlisting">#include &lt;boost/date_time/posix_time/posix_time.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::posix_time::ptime pt1(boost::gregorian::date(2009, 1, 05), boost::posix_time::time_duration(12, 0, 0)); 
  boost::posix_time::ptime pt2(boost::gregorian::date(2009, 1, 05), boost::posix_time::time_duration(18, 30, 0)); 
  boost::posix_time::time_period tp(pt1, pt2); 
  std::cout &lt;&lt; tp.contains(pt1) &lt;&lt; std::endl; 
  std::cout &lt;&lt; tp.contains(pt2) &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/10.3.6/main.cpp">Download source code</a></li></ul>
<p>In general <code class="classname">boost::posix_time::time_period</code> works exactly like <code class="classname">boost::gregorian::date_period</code>. It provides a method named <code class="methodname">contains()</code> which returns <code class="literal">true</code> for every point in time within the period. Since the end time, passed to the constructor of <code class="classname">boost::posix_time::time_period</code>, is not part of the period, above example returns <code class="literal">false</code> for the second call of <code class="methodname">contains()</code>.</p>
<p><code class="classname">boost::posix_time::time_period</code> also offers additional methods such as <code class="methodname">intersection()</code> and <code class="methodname">merge()</code> to calculate the intersection of two overlapping periods or to merge two intersecting periods, respectively.</p>
<p>Finally, the iterator <code class="classname">boost::posix_time::time_iterator</code> is introduced to iterate over points in time.</p>
<pre class="programlisting">#include &lt;boost/date_time/local_time/local_time.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::posix_time::ptime pt(boost::gregorian::date(2009, 1, 05), boost::posix_time::time_duration(12, 0, 0)); 
  boost::posix_time::time_iterator it(pt, boost::posix_time::time_duration(6, 30, 0)); 
  std::cout &lt;&lt; *++it &lt;&lt; std::endl; 
  std::cout &lt;&lt; *++it &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/10.3.7/main.cpp">Download source code</a></li></ul>
<p>The application uses the iterator <var>it</var> to jump forward 6.5 hours starting at time <var>pt</var>. Since the iterator is incremented twice, the corresponding output is <code class="computeroutput">2009-Jan-05 18:30:00</code> and <code class="computeroutput">2009-Jan-06 01:00:00</code>.</p>
</div>
<hr>
<h2 class="title">
<a name="datetime_location_dependent_times"></a>10.4 Location-dependent Times</h2>
<div class="sect1">
<p>Unlike the location-independent times introduced in the previous section, location-dependent times actually account for time zones. For this purpose, Boost.DateTime offers the <code class="classname">boost::local_time::local_date_time</code> class, defined in <code class="filename">boost/date_time/local_time/local_time.hpp</code>, which uses <code class="classname">boost::local_time::posix_time_zone</code> to store time zone information.</p>
<pre class="programlisting">#include &lt;boost/date_time/local_time/local_time.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::local_time::time_zone_ptr tz(new boost::local_time::posix_time_zone("CET+1")); 
  boost::posix_time::ptime pt(boost::gregorian::date(2009, 1, 5), boost::posix_time::time_duration(12, 0, 0)); 
  boost::local_time::local_date_time dt(pt, tz); 
  std::cout &lt;&lt; dt.utc_time() &lt;&lt; std::endl; 
  std::cout &lt;&lt; dt &lt;&lt; std::endl; 
  std::cout &lt;&lt; dt.local_time() &lt;&lt; std::endl; 
  std::cout &lt;&lt; dt.zone_name() &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/10.4.1/main.cpp">Download source code</a></li></ul>
<p>The constructor of <code class="classname">boost::local_time::local_date_time</code> expects an object of type <code class="classname">boost::posix_time::ptime</code> as its first argument as well as an object of type <code class="type">boost::local_time::time_zone_ptr</code> as its second. This is merely a type definition for <code class="code">boost::shared_ptr&lt;boost::local_time::posix_time_zone&gt;</code>. In other words, no object of type <code class="classname">boost::local_time::posix_time_zone</code> is passed but rather a smart pointer pointing to one. This allows multiple objects of type <code class="classname">boost::local_time::local_date_time</code> to share time zone information. Only if the last object is destroyed, the corresponding object representing the time zone is automatically released.</p>
<p>To create an object of type <code class="classname">boost::local_time::posix_time_zone</code>, a string describing the time zone is passed to the constructor as the single argument. The above example specifies Central Europe as the time zone: CET is the abbreviation for Central European Time. Since CET is one hour ahead of UTC, the deviation is denoted as +1 accordingly. Boost.DateTime is not able to interpret abbreviations for time zones and thus does not know the meaning of CET. Therefore, the deviation must always be provided in hours; passing +0 means no deviation.</p>
<p>When executed, the application will write <code class="computeroutput">2009-Jan-05 12:00:00</code>, <code class="computeroutput">2009-Jan-05 13:00:00 CET</code>, <code class="computeroutput">2009-Jan-05 13:00:00</code> and <code class="computeroutput">CET</code> to the standard output stream. Values used to initialize objects of type <code class="classname">boost::posix_time::ptime</code> and <code class="classname">boost::local_time::local_date_time</code> always relate to the UTC time zone by default. Only if an object of type <code class="classname">boost::local_time::local_date_time</code> is written to the standard output stream or a call to the <code class="methodname">local_time()</code> method is made, the deviation in hours is used for calculating the local time.</p>
<pre class="programlisting">#include &lt;boost/date_time/local_time/local_time.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::local_time::time_zone_ptr tz(new boost::local_time::posix_time_zone("CET+1")); 
  boost::posix_time::ptime pt(boost::gregorian::date(2009, 1, 5), boost::posix_time::time_duration(12, 0, 0)); 
  boost::local_time::local_date_time dt(pt, tz); 
  std::cout &lt;&lt; dt.local_time() &lt;&lt; std::endl; 
  boost::local_time::time_zone_ptr tz2(new boost::local_time::posix_time_zone("EET+2")); 
  std::cout &lt;&lt; dt.local_time_in(tz2).local_time() &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/10.4.2/main.cpp">Download source code</a></li></ul>
<p>By using the  <code class="methodname">local_time()</code> method, the deviation for the time zone is actually respected. In order to calculate the CET time, one hour needs to be added to the UTC time of 12 PM stored in <var>dt</var> since CET is one hour ahead of UTC. <code class="methodname">local_time()</code> writes <code class="computeroutput">2009-Jan-05 13:00:00</code> to the standard output stream accordingly.</p>
<p>In contrast, the <code class="methodname">local_time_in()</code> method interprets the time stored in <var>dt</var> as being in the time zone passed as the argument. This means that 12 PM UTC equals 2 PM EET which stands for Eastern European Time and is two hours ahead of UTC.</p>
<p>Finally, location-dependent periods are offered by Boost.DateTime via the <code class="classname">boost::local_time::local_time_period</code> class.</p>
<pre class="programlisting">#include &lt;boost/date_time/local_time/local_time.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::local_time::time_zone_ptr tz(new boost::local_time::posix_time_zone("CET+0")); 
  boost::posix_time::ptime pt1(boost::gregorian::date(2009, 1, 5), boost::posix_time::time_duration(12, 0, 0)); 
  boost::local_time::local_date_time dt1(pt1, tz); 
  boost::posix_time::ptime pt2(boost::gregorian::date(2009, 1, 5), boost::posix_time::time_duration(18, 0, 0)); 
  boost::local_time::local_date_time dt2(pt2, tz); 
  boost::local_time::local_time_period tp(dt1, dt2); 
  std::cout &lt;&lt; tp.contains(dt1) &lt;&lt; std::endl; 
  std::cout &lt;&lt; tp.contains(dt2) &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/10.4.3/main.cpp">Download source code</a></li></ul>
<p>The constructor of <code class="classname">boost::local_time::local_time_period</code> expects two arguments of type <code class="classname">boost::local_time::local_date_time</code>. As with the other data types provided for periods, the second argument, representing the end time, is not part of the actual period. With the help of methods such as <code class="methodname">contains()</code>, <code class="methodname">intersection()</code>, <code class="methodname">merge()</code> and others, periods can be processed with <code class="classname">boost::local_time::local_time_period</code> accordingly.</p>
</div>
<hr>
<h2 class="title">
<a name="datetime_formatted_io"></a>10.5 Formatted Input and Output</h2>
<div class="sect1">
<p>Any example in this chapter provided results such as <code class="computeroutput">2009-Jan-07</code> once executed. Some people may actually prefer a different format to display the results. Boost.DateTime allows to format calendar dates and times via the <code class="classname">boost::date_time::date_facet</code> and <code class="classname">boost::date_time::time_facet</code> classes.</p>
<pre class="programlisting">#include &lt;boost/date_time/gregorian/gregorian.hpp&gt; 
#include &lt;iostream&gt; 
#include &lt;locale&gt; 

int main() 
{ 
  boost::gregorian::date d(2009, 1, 7); 
  boost::gregorian::date_facet *df = new boost::gregorian::date_facet("%A, %d %B %Y"); 
  std::cout.imbue(std::locale(std::cout.getloc(), df)); 
  std::cout &lt;&lt; d &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/10.5.1/main.cpp">Download source code</a></li></ul>
<p>Boost.DateTime uses the concept of locales known from the C++ standard introduced in a nutshell in <a class="xref" href="stringhandling.html" title="Chapter 5: String Handling">Chapter 5, <i>String Handling</i></a>. To format a calendar date, an object of type <code class="classname">boost::date_time::date_facet</code> must be created and installed within a locale. A string describing the new format is passed to the constructor of <code class="classname">boost::date_time::date_facet</code>. The example passes <code class="literal">%A, %d %B %Y</code> specifying that the day of the week is followed by the date with the month written in full: <code class="computeroutput">Wednesday, 07 January 2009</code>.</p>
<p>Boost.DateTime offers numerous format flags that consist of the percent sign followed by a character. The documentation of Boost.DateTime contains a complete overview over all supported flags. For example, %A specifies the name of the weekday.</p>
<p>If the user base of the application is located in Germany or German-speaking countries, it is preferable to display both the weekday and the month in German rather than in English.</p>
<pre class="programlisting">#include &lt;boost/date_time/gregorian/gregorian.hpp&gt; 
#include &lt;iostream&gt; 
#include &lt;locale&gt; 
#include &lt;string&gt; 
#include &lt;vector&gt; 

int main() 
{ 
  std::locale::global(std::locale("German")); 
  std::string months[12] = { "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember" }; 
  std::string weekdays[7] = { "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag" }; 
  boost::gregorian::date d(2009, 1, 7); 
  boost::gregorian::date_facet *df = new boost::gregorian::date_facet("%A, %d. %B %Y"); 
  df-&gt;long_month_names(std::vector&lt;std::string&gt;(months, months + 12)); 
  df-&gt;long_weekday_names(std::vector&lt;std::string&gt;(weekdays, weekdays + 7)); 
  std::cout.imbue(std::locale(std::cout.getloc(), df)); 
  std::cout &lt;&lt; d &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/10.5.2/main.cpp">Download source code</a></li></ul>
<p>The names for weekdays and months can be changed by passing vectors containing corresponding names to the <code class="methodname">long_month_names()</code> and <code class="methodname">long_weekday_names()</code> methods of the <code class="classname">boost::date_time::date_facet</code> class. The above example now writes <code class="computeroutput">Mittwoch, 07. Januar 2009</code> to the standard output stream.</p>
<p>Boost.DateTime is pretty flexible in regards to formatted input and output. Besides the output classes <code class="classname">boost::date_time::date_facet</code> and <code class="classname">boost::date_time::time_facet</code>, the classes <code class="classname">boost::date_time::date_input_facet</code> and <code class="classname">boost::date_time::time_input_facet</code> are available for formatted input. All four classes provide many methods to configure the input and output of the different objects provided by Boost.DateTime. For example, it is possible to specify how periods of type <code class="classname">boost::gregorian::date_period</code> are input and output. Due to the manifold possibilities for formatted input and output it is essential to review the documentation of Boost.DateTime.</p>
</div>
<hr>
<h2 class="title">
<a name="datetime_exercises"></a>10.6 Exercises</h2>
<div class="sect1">
<p class="solution">
              You can buy 
              <a target="_top" href="http://en.highscore.de/shop/index.php?p=boost-solution">solutions to all exercises</a>
              in this book as a ZIP file. 
            </p>
<ol>
<li class="listitem"><p>Create an application that writes the weekdays for the next Christmas Eve, Christmas Day and the following day to the standard output stream.</p></li>
<li class="listitem"><p>Calculate your age in days. The application should determine the current date for the computation automatically.</p></li>
</ol>
</div>
</div>
<hr class="hrfoot">
<p class="copyright">Copyright © 2008-2010 
        <a class="link" href="mailto:boris@highscore.de">Boris Schäling</a>
      </p>
</body>
</html>
